#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>         //https://github.com/tzapu/WiFiManager

#include <ESP8266TimerInterrupt.h>

#include <ArduinoJson.h>
#include <MQTT.h>

#define MQTT_HEART_TIMER_INTERVAL_MS        5000 

const char* mqtt_server = "mq.tongxinmao.com";//MQTT服务器的地址 
const int mqtt_port=18830;//MQTT服务器端口号
String m_ChipId;
int relayPin = 14; //继电器引脚
int relayPin2 = 4; 
bool isopen = false;

WiFiClient net;
MQTTClient mqttclient;
ESP8266Timer mqttheartTimer;

void ICACHE_RAM_ATTR mqtt_heart_TimerHandler(void)
{
  if(!mqttclient.connected()) 
    return;
    
  String tmpStr = "{device:"+m_ChipId+",'status':'on'}";
  mqttclient.publish("home/status/",tmpStr.c_str() );
}

void mqtt_reconnect() {//等待，直到连接上服务器
  while (!mqttclient.connected()) {//如果没有连接上
    if (mqttclient.connect("biloba"+random(999999999))) {//接入时的用户名，尽量取一个很不常用的用户名
      Serial.println("mqtt server connected.");
      mqttclient.subscribe("AKINGLED",2);//接收外来的数据时的intopic
      Serial.println("message LED subscribe success.");
    } else {
      Serial.println("connect mqtt server failed,try again connect mqtt server in 5 seconds");//延时5秒后重新连接           
      delay(5000);
    }
  }
}

void mqtt_messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);

  StaticJsonDocument<200> doc; //声明一个JsonDocument对象
  DeserializationError error = deserializeJson(doc, payload); //反序列化JSON数据

  if(!error) {
    String action = doc["action"];
   
    if (action.equals("off") == true) {
      digitalWrite(relayPin, HIGH);   // 亮灯
      digitalWrite(2, HIGH);   // 亮灯
      Serial.println("digitalWrite on");
    }
    else if (action.equals("on") == true) {
      digitalWrite(relayPin, LOW);   // 亮灯
      digitalWrite(2, LOW);   // 亮灯
      Serial.println("digitalWrite off");
    }
  }
}

void setup() {
    Serial.begin(115200);

    pinMode(2, OUTPUT);  
    delay(100);
    pinMode(relayPin, OUTPUT);   
    delay(100);
    pinMode(relayPin2,INPUT); 

    digitalWrite(2, HIGH);
    digitalWrite(relayPin, HIGH);    

    WiFiManager wifiManager;

    wifiManager.setTimeout(180);
    //wifiManager.setConnectTimeout(120);
    wifiManager.setAPStaticIPConfig(IPAddress(192,168,4,1), IPAddress(192,168,4,1), IPAddress(255,255,255,0));

    m_ChipId = (String)ESP.getChipId();
    String apName = ("ESP_"+m_ChipId);  
    wifiManager.autoConnect(apName.c_str(),apName.c_str());

    mqttclient.begin(mqtt_server,mqtt_port, net);
    mqttclient.onMessage(mqtt_messageReceived);  

    mqttheartTimer.attachInterruptInterval(MQTT_HEART_TIMER_INTERVAL_MS * 1000, mqtt_heart_TimerHandler);

    Serial.println("connected... :)");
}

void loop() {
  if(WiFi.status() == WL_CONNECTED) {
    if (!mqttclient.connected()) {
     mqtt_reconnect();//确保连上服务器，否则一直等待。
    }
    else {
     mqttclient.loop();//MUC接收数据的主循环函数。
     delay(10);
    }  
  }  

  int pirValue = digitalRead(relayPin2);
  Serial.println(pirValue);
  
  if(pirValue == 1) {
      if(!isopen) {
        isopen = true;
        digitalWrite(relayPin, LOW);   // 亮灯
      }
  }
  else {
      if(isopen) {
        isopen = false;
        digitalWrite(relayPin, HIGH);   // 亮灯
      }
  }
}
